package com.hllxd.hism.framework.rpc.client.basic;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.hllxd.hism.framework.rpc.client.basic.dto.RequestDto;
import com.hllxd.hism.framework.rpc.client.basic.dto.ResponseDto;
import com.hllxd.hism.framework.rpc.client.config.client.ServiceProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author xiyong.lxy
 * @date 2020-10-12 19:45
 */
@Slf4j
@Component("rpcInvoker")
public class RpcInvoker {
    @Autowired
    private ServiceProperties serviceProperties;

    private static Map<String,RpcHttpClient> localGrpcConfigMap = new ConcurrentHashMap<String, RpcHttpClient>();
    @PostConstruct
    private void initLocalGrpcConfigMap() {
        Map<String,String> serviceHostMap = serviceProperties.getHosts();
        if (serviceHostMap==null || serviceHostMap.size()==0) {
            log.info("serviceHostMap is not config.");
            return;
        }
        for(Map.Entry<String,String> entry : serviceHostMap.entrySet()) {
            String service = entry.getKey();
            String hosts = entry.getValue();
            log.info("Initializing gRpc client...{}:{}",service, hosts);
            RpcHttpClient client = grpcClientCreate(hosts);
            localGrpcConfigMap.put(service, client);
        }
    }
    // 访问接口
    public RpcResData<String> invoke(String service, RpcReqData reqData) throws Exception{

        RpcHttpClient grpcClient = getGrpcClient(service);
        if(grpcClient==null){
            throw new RuntimeException("服务无效");
        }

        ResponseDto response = grpcClient.request(new RequestDto(reqData.getTraceID(), JSON.toJSONString(reqData, SerializerFeature.DisableCircularReferenceDetect)));
        if(response==null) {
            log.warn("request failed.");
            return null;
        }
        RpcResData<String> rpcResData=new RpcResData<String>();
        rpcResData.setData(response.getData());
        rpcResData.setCode(response.getResult().getCode());
        rpcResData.setTraceID(reqData.getTraceID());
        rpcResData.setMessage(response.getResult().getMessage());
        return rpcResData;
    }

    private RpcHttpClient getGrpcClient(String service) { // string version
        if(service==null || service.isEmpty()) {
            log.warn("service name is invalid. {}", service);
            return null;
        }
        try {
            return localGrpcConfigMap.get(service);
        } catch (Exception e) {
            log.error("Exception: {}, {}.", e.toString(), service);
            return null;
        }
    }
    private RpcHttpClient grpcClientCreate(String hosts) {
        RpcHttpClient grpcClient = new RpcHttpClient(hosts);
        try {
            grpcClient.afterPropertiesSet();
        } catch (Exception e) {
            log.error("init failed.{}",e.toString(),e);
        }
        grpcClient.withDeadLine(60000L);
        return grpcClient;
    }

}
